package com.syh.jn.scm.infrastructure.repository.impl.downstream.base;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AbstractAggregateRepository;
import com.syh.core.expction.UnexpectedlyException;
import com.syh.jn.scm.domain.downstream.entity.base.logistics.DownLogistics;
import com.syh.jn.scm.domain.downstream.entity.base.logistics.DownLogisticsAddress;
import com.syh.jn.scm.domain.downstream.entity.base.logistics.DownLogisticsTruck;
import com.syh.jn.scm.domain.downstream.repository.base.DownLogisticsRepository;
import com.syh.jn.scm.dto.downstream.base.logistics.DownLogisticsVo;
import com.syh.jn.scm.dto.downstream.base.logistics.logisticsAddress.DownLogisticsAddressVo;
import com.syh.jn.scm.dto.downstream.base.logistics.logisticsTruck.DownLogisticsTruckVo;
import com.syh.jn.scm.infrastructure.repository.model.base.logistics.LogisticsAddressModel;
import com.syh.jn.scm.infrastructure.repository.model.base.logistics.LogisticsModel;
import com.syh.jn.scm.infrastructure.repository.model.base.logistics.LogisticsTruckModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
public class DownLogisticsRepositoryImpl extends AbstractAggregateRepository<DownLogistics, LogisticsModel, Long> implements DownLogisticsRepository {
  /**
   * 新增物流
   * @param downLogistics
   * @return
   */
  @Override
  public Long add(DownLogistics downLogistics) {
    LogisticsModel logisticsModel = LogisticsModel.builder().build();
    logisticsModel.setTerminalType("DOWNSTREAM");
    ExtBeanUtils.copyProperties(downLogistics,logisticsModel);
    return (Long)super.hibernateTemplate.save(logisticsModel);
  }

  /**
   * 删除对象以及相关的地址和车型报价
   * @param logistics
   */
  @Override
  public void remove(DownLogistics logistics) {
    //删除物流相关服务地址
    StringBuffer addressHql = new StringBuffer();
    addressHql.append("from LogisticsAddressModel model where model.logisticsId = ?");
    List<LogisticsAddressModel> addressModels = (List<LogisticsAddressModel>) this.hibernateTemplate.find(addressHql.toString(), logistics.getId());
    if (addressModels != null && addressModels.size() > 0) {
      addressModels.stream().forEach((addressModel)->{
        this.hibernateTemplate.delete(addressModel);
      });
    }
    //删除物流相关车辆信息
    StringBuffer truckHql = new StringBuffer();
    truckHql.append("from LogisticsTruckModel model where model.logisticsId = ?");
    List<LogisticsTruckModel> truckModels = (List<LogisticsTruckModel>) this.hibernateTemplate.find(truckHql.toString(), logistics.getId());
    if (truckModels != null && truckModels.size() > 0) {
      truckModels.stream().forEach((truckModel)->{
        this.hibernateTemplate.delete(truckModel);
      });
    }
    super.remove(logistics);
  }

  /**
   * 批量增加地址
   * @param addressList
   */
  @Override
  public void batchSaveAddress(List<DownLogisticsAddress> addressList) {
    addressList.stream().forEach((address)->{
      LogisticsAddressModel model = new LogisticsAddressModel();
      ExtBeanUtils.copyProperties(address, model);
      this.hibernateTemplate.save(model);
    });
  }

  /**
   * 批量修改地址
   * @param addressList
   */
  @Override
  public void batchModifyAddress(List<DownLogisticsAddress> addressList) {
    addressList.stream().forEach((address)->{
      LogisticsAddressModel model = this.hibernateTemplate.get(LogisticsAddressModel.class, address.getId());
      ExtBeanUtils.copyProperties(address, model);
    });
  }

  /**
   * 批量增加车型
   * @param truckList
   */
  @Override
  public void batchSaveTruck(List<DownLogisticsTruck> truckList) {
    truckList.stream().forEach((truck)->{
      LogisticsTruckModel model = new LogisticsTruckModel();
      ExtBeanUtils.copyProperties(truck, model);
      this.hibernateTemplate.save(model);
    });
  }

  /**
   * 批量修改车型
   * @param truckList
   */
  @Override
  public void batchModifyTruck(List<DownLogisticsTruck> truckList) {
    truckList.stream().forEach((truck)->{
      LogisticsTruckModel model = this.hibernateTemplate.get(LogisticsTruckModel.class, truck.getId());
      ExtBeanUtils.copyProperties(truck, model);
    });
  }

  /**
   * 根据地址id删除
   * @param address
   */
  @Override
  public void deleteAddress(DownLogisticsAddress address) {
    LogisticsAddressModel model = this.hibernateTemplate.get(LogisticsAddressModel.class, address.getId());
    if (model != null) {
      this.hibernateTemplate.delete(model);
    }
  }

  /**
   * 根据车型id删除
   * @param truck
   */
  @Override
  public void deleteTruck(DownLogisticsTruck truck) {
    LogisticsTruckModel model = this.hibernateTemplate.get(LogisticsTruckModel.class, truck.getId());
    if (model != null) {
      this.hibernateTemplate.delete(model);
    }
  }

  /**
   * 根据addressId查地址
   * @param addressId
   * @return
   */
  @Override
  public DownLogisticsAddress getByAddressId(Long addressId) {
    try {
      LogisticsAddressModel model = this.hibernateTemplate.get(LogisticsAddressModel.class, addressId);
      if (model == null) {
        return null;
      }
      DownLogisticsAddress entity = new DownLogisticsAddress();
      ExtBeanUtils.copyProperties(model, entity);
      return entity;
    } catch (Exception e) {
      throw new UnexpectedlyException(e);
    }
  }

  /**
   * 根据truckId查车型
   * @param truckId
   * @return
   */
  @Override
  public DownLogisticsTruck getByTruckId(Long truckId) {
    try {
      LogisticsTruckModel model = this.hibernateTemplate.get(LogisticsTruckModel.class, truckId);
      if (model == null) {
        return null;
      }
      DownLogisticsTruck entity = new DownLogisticsTruck();
      ExtBeanUtils.copyProperties(model, entity);
      return entity;
    } catch (Exception e) {
      throw new UnexpectedlyException(e);
    }
  }

  /**
   * 根据id获取地址列表
   * @param logisticsId
   * @return
   */
  @Override
  public List<DownLogisticsAddressVo> getAddressListById(Long logisticsId) {
    StringBuffer addressHql = new StringBuffer();
    addressHql.append("from LogisticsAddressModel model where model.logisticsId = ?");
    List<LogisticsAddressModel> addressModels = (List<LogisticsAddressModel>) this.hibernateTemplate.find(addressHql.toString(), logisticsId);
    if (addressModels.isEmpty()) {
      return Collections.emptyList();
    }
    return this.transAddressForm(addressModels);
  }

  /**
   * 根据id获取服务车型列表
   * @param logisticsId
   * @return
   */
  @Override
  public List<DownLogisticsTruckVo> getTruckListById(Long logisticsId) {
    StringBuffer truckHql = new StringBuffer();
    truckHql.append("from LogisticsTruckModel model where model.logisticsId = ?");
    List<LogisticsTruckModel> truckModels = (List<LogisticsTruckModel>) this.hibernateTemplate.find(truckHql.toString(), logisticsId);
    if (truckModels.isEmpty()) {
      return Collections.emptyList();
    }
    return this.transTruckForm(truckModels);
  }

  /**
   * 内部方法  业务模型转LogisticsTruckVo
   * @param entityList
   * @return
   */
  private List<DownLogisticsTruckVo> transTruckForm(List<LogisticsTruckModel> entityList) {
    List<DownLogisticsTruckVo> voList = new ArrayList<>();
    entityList.stream().forEach((entity)->{
      DownLogisticsTruckVo vo = new DownLogisticsTruckVo();
      ExtBeanUtils.copyProperties(entity, vo);
      voList.add(vo);
    });
    return voList;
  }

  /**
   * 内部方法  业务模型转LogisticsAddressVo
   * @param entityList
   * @return
   */
  private List<DownLogisticsAddressVo> transAddressForm(List<LogisticsAddressModel> entityList) {
    List<DownLogisticsAddressVo> voList = new ArrayList<>();
    entityList.stream().forEach((entity)->{
      DownLogisticsAddressVo vo = new DownLogisticsAddressVo();
      ExtBeanUtils.copyProperties(entity, vo);
      voList.add(vo);
    });
    return voList;
  }

  @Override
  protected SQL getViewSql() {
    return new SQL() {{
      SELECT(
              SQLAliasGenerateUtil.aliasGenerate(LogisticsModel.class, "downLogistics", null)
      );
      FROM("T_BASE_LOGISTICS downLogistics");
    }};
  }

  @Override
  protected Class getViewObject() {
    return DownLogisticsVo.class;
  }

  @Override
  protected BaseResolve getViewWrapperResolve(Wrapper wrapper) {
    Map<String, String> params = new HashMap<>();
    params.put("id", "downLogistics.ID");
    params.put("name", "downLogistics.NAME");
    params.put("isProvide", "downLogistics.IS_PROVIDE");
    params.put("terminalType", "downLogistics.TERMINAL_TYPE");
    params.put("status", "downLogistics.STATUS");
    params.put("businessEntityId", "downLogistics.BUSINESS_ENTITY_ID");
    ResolveToSQL parse = new ResolveToSQL(wrapper, (propertyName) -> {
      return params.get(propertyName);
    });
    return parse;
  }

  @Override
  protected <T> List<T> superFindListPageView(Wrapper wrapper, Integer startRow, Integer count) {
    wrapper.append(Restrictions.eq("terminalType", "DOWNSTREAM"));
    return super.superFindListPageView(wrapper, startRow, count);
  }
}
